import hashlib
import re
import traceback
from collections.abc import Generator
from datetime import datetime
from typing import Any

import oss2
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage


class HtmlToOssTool(Tool):
    def _invoke(self, 
                tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
        html_content = tool_parameters.get("html_content", "")
        project_name = tool_parameters.get("project_name", "")

        credentials = self.runtime.credentials
        # Get OSS credentials from provider credentials
        oss_access_key_id = credentials.get("oss_access_key_id", "")
        oss_access_key_secret = credentials.get("oss_access_key_secret", "")
        oss_bucket_name = credentials.get("oss_bucket_name", "")
        oss_endpoint = credentials.get("oss_endpoint", "")

        if not html_content.strip():
            yield self.create_text_message("错误：请提供HTML内容")
            return

        # 生成项目名称（如果未提供）
        if not project_name:
            content_hash = hashlib.md5(html_content.encode()).hexdigest()[:8]
            project_name = f"html-app-{content_hash}"

        # 清理项目名称
        project_name = re.sub(r"[^a-zA-Z0-9-]", "-", project_name.lower())

        yield self.create_text_message(f"开始部署HTML页面: {project_name}")

        # 尝试使用阿里云OSS部署
        deployment_url, oss_error = self._deploy_to_aliyun_oss(
            project_name,
            html_content,
            oss_access_key_id,
            oss_access_key_secret,
            oss_bucket_name,
            oss_endpoint,
        )

        if deployment_url:
            # 直接返回OSS链接地址
            yield self.create_text_message(f"HTML页面部署成功！访问链接: {deployment_url}")
            yield self.create_json_message({
                "success": True,
                "platform": "Aliyun OSS",
                "project_name": project_name,
                "deployment_url": deployment_url,
                "message": f"HTML页面已成功部署到阿里云OSS！访问链接: {deployment_url}"
            })
            return

        # 回退方案：提供HTML文件下载和部署指南
        yield self.create_json_message({
            "success": False,
            "message": f"OSS部署失败: {oss_error}",
            "fallback": "请手动部署HTML内容"
        })
        
        yield self.create_blob_message(
            blob=html_content.encode("utf-8"),
            meta={"mime_type": "text/html", "filename": f"{project_name}.html"},
        )

    def _deploy_to_aliyun_oss(
        self,
        project_name: str,
        html_content: str,
        access_key_id: str,
        access_key_secret: str,
        bucket_name: str,
        endpoint: str,
    ) -> tuple[str, str]:
        """使用阿里云OSS部署，返回(URL, 错误信息)"""
        try:
            # Validate OSS credentials - endpoint is now optional
            if not all([access_key_id, access_key_secret, bucket_name]):
                return None, "缺少必要的OSS凭证"

            # Use default endpoint if none provided
            if not endpoint or not isinstance(endpoint, str):
                endpoint = "oss-cn-hangzhou.aliyuncs.com"  # Changed to public endpoint

            # Create OSS client
            auth = oss2.Auth(access_key_id, access_key_secret)
            bucket = oss2.Bucket(auth, endpoint, bucket_name)

            # Generate filename
            filename = f"{project_name}-{datetime.now().strftime('%Y%m%d%H%M%S')}.html"

            # Upload HTML file
            bucket.put_object(
                filename,
                html_content.encode("utf-8"),
                headers={
                    "Content-Type": "text/html",
                    "Content-Disposition": "inline"
                },
            )

            # Generate presigned URL (valid for 24 hours)
            signed_url = bucket.sign_url("GET", filename, 24 * 3600)

            return signed_url, None
        except Exception as e:
            tb = traceback.format_exc()
            return None, f"Aliyun OSS部署失败: {e}\n\n完整错误信息:\n{tb}"

    def _create_downloadable_app(
        self, project_name: str, html_content: str, js_content: str, css_content: str
    ) -> dict:
        """创建可下载的应用文件信息"""

        return {
            "filename": f"{project_name}.html",
            "content": html_content,
            "size": len(html_content),
            "download_instructions": {
                "zh": [
                    "1. 复制下面的HTML内容",
                    "2. 保存为 {}.html 文件".format(project_name),
                    "3. 选择以下任一免费托管服务上传:",
                    "   • Netlify Drop: 直接拖拽文件到 netlify.com/drop",
                    "   • Vercel: 连接GitHub仓库自动部署",
                    "   • GitHub Pages: 推送到GitHub仓库并启用Pages",
                    "   • Surge.sh: 使用命令行工具 'surge' 部署",
                ],
                "en": [
                    "1. Copy the HTML content below",
                    "2. Save as {}.html file".format(project_name),
                    "3. Upload to any of these free hosting services:",
                    "   • Netlify Drop: Drag & drop to netlify.com/drop",
                    "   • Vercel: Connect GitHub repo for auto-deploy",
                    "   • GitHub Pages: Push to GitHub repo and enable Pages",
                    "   • Surge.sh: Use 'surge' CLI tool to deploy",
                ],
            },
            "hosting_services": [
                {
                    "name": "Netlify Drop",
                    "url": "https://app.netlify.com/drop",
                    "description": "最简单：拖拽HTML文件即可部署",
                    "steps": [
                        "访问 netlify.com/drop",
                        "拖拽HTML文件到页面",
                        "获得部署链接",
                    ],
                },
                {
                    "name": "Vercel",
                    "url": "https://vercel.com",
                    "description": "专业：连接GitHub仓库自动部署",
                    "steps": ["创建GitHub仓库", "上传HTML文件", "连接Vercel自动部署"],
                },
                {
                    "name": "GitHub Pages",
                    "url": "https://pages.github.com",
                    "description": "免费：GitHub提供的静态网站托管",
                    "steps": ["创建GitHub仓库", "上传HTML文件", "在设置中启用Pages"],
                },
                {
                    "name": "Surge.sh",
                    "url": "https://surge.sh",
                    "description": "命令行：适合开发者的部署工具",
                    "steps": [
                        "安装surge: npm install -g surge",
                        "在文件目录运行: surge",
                        "选择域名完成部署",
                    ],
                },
            ],
            "quick_deploy_tip": {
                "zh": "推荐使用Netlify Drop，只需拖拽文件即可获得可访问的网站链接！",
                "en": "Recommended: Use Netlify Drop - just drag & drop the file to get a live website link!",
            },
        }
